/**
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) 2010  Sean Beecroft

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.

 * @version 1.10 2010-01-01
 * @author Sean Beecroft
 */
package yawiki.server.application;

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

import yawiki.server.database.*;
import yawiki.server.symbols.Document;
import yawiki.server.template.Template;
import yawiki.server.template.TemplateFactory;
import yawiki.server.util.StringUtility;
import yawiki.server.util.Toolbox;

import java.sql.*;
import java.net.*;

public class Yawiki extends HttpServlet {

    DbConnectionBroker broker;
    int count = 0;

    public void init(ServletConfig config) throws ServletException {
        super.init(config);
        try {
            broker = new DbConnectionBroker(
                    Messages.getString("Yawiki.driver"),
                    Messages.getString("Yawiki.connection"),
                    Messages.getString("Yawiki.userid"),
                    Messages.getString("Yawiki.password"), 5, 24,
                    Messages.getString("Yawiki.log"), 1.0);

            TemplateFactory.cacheTemplate("www");
            //TemplateFactory.cacheTemplate("create");


        } catch (IOException e5) {
            System.out.println(e5);
            e5.printStackTrace();
        }
    }

    public String setup(String page) {
        page = page.replaceAll("http://www." + Globals.domain + Globals.context, "");
        page = page.replaceAll("http://" + Globals.domain + Globals.context, "");
        page = page.replaceAll("http://localhost" + Globals.context, "");
        if (page.indexOf("http://") != -1) {
            int indx = page.indexOf(".");

            if (indx != -1) {
                String keyword = page.substring("http://".length(), indx);
                System.out.println(keyword);
                page = StringUtility.capitalize(keyword);
            }

        }

        page = page.replaceAll("_", " ");  //$NON-NLS-2$
        page = page.replaceAll("'", "&apos;");  //$NON-NLS-2$

        page = StringUtility.capitalize(page);
        page = page.trim();
        try {
            page = URLDecoder.decode(page, "UTF-8");
        } catch (UnsupportedEncodingException ex) {
            //Logger.getLogger(Yawiki.class.getName()).log(Level.SEVERE, null, ex);
        }
        return page;
    }

    public Template load(Template template, String page) {
        String title = page;

        String spage = page.replaceAll(" ", "_");
        long snap = System.currentTimeMillis();
        String lastUpdated = "";

        String keywords = Globals.htmlKeywords;
        String description = Globals.htmlDescription;
        String author = Globals.htmlAuthor;
        String copyright = Globals.htmlCopyright;

        template.registerSymbol("__CONTEXT__", Globals.context);
        template.registerSymbol("__DOMAIN__", Globals.domain);
        template.registerSymbol("__PAGE__", page);
        template.registerSymbol("__TERM__", title);
        template.registerSymbol("__TITLE__", title);
        template.registerSymbol("__KEYWORDS__", keywords);
        template.registerSymbol("__LAST_UPDATED__", lastUpdated);
        template.registerSymbol("__DESCRIPTION__", description);
        template.registerSymbol("__COPYRIGHT__", copyright);
        template.registerSymbol("__AUTHOR__", author);
        return template;
    }

    public void doGet(HttpServletRequest request,
            HttpServletResponse response)
            throws IOException, ServletException {
        count++;
        try {
            request.setCharacterEncoding("UTF-8");
            response.setContentType(Globals.htmlContentType);

            System.out.println("Count:" + count);
            String page = null;
            Connection conn = null;
            Template template = null;
            try {

                page = request.getRequestURL().toString();

                //////////////////////////////////////////////////////////////////////////
                System.out.println(page);
                String templateName = "www";
                template = new Template(TemplateFactory.getTemplate(templateName));

                page = setup(page);

            } catch (Exception ex) {
                System.out.println("Exception in page load:" + ex);
            }
            BufferedWriter out = new BufferedWriter(new OutputStreamWriter(response.getOutputStream(), "UTF8"));

            template = load(template, page);

            if (request == null) {
                System.out.println("request was null");
            }

            long dbsnap = System.currentTimeMillis();
            long parserSnap = 0;

            handlePage(page, conn, dbsnap, template, parserSnap, response, out);

            // The connection is returned to the Broker
            broker.freeConnection(conn);

            out.flush();
            out.close();

        } catch (Exception ex) {
            System.out.println(ex);
        }
    }

    public void handlePage(String page, Connection conn, long dbsnap, Template template, long parserSnap, HttpServletResponse response, BufferedWriter out) {
        try {

            conn = broker.getConnection();
            int con = broker.idOfConnection(conn);

            Statement statement = null;
            System.out.println("Creating statement object[" + page + "]");
            statement = conn.createStatement();

            if (page == null) {
                System.out.println("page is null");
            }

            String pageTitle = Toolbox.straighten(page);
            String sql = "SELECT * from yawiki_resource where title = '" + pageTitle + "' ";
            ResultSet r = statement.executeQuery(sql);
            System.out.println(sql);

            dbsnap = System.currentTimeMillis() - dbsnap;
            template.registerSymbol("__DB_SNAP__", "" + dbsnap);

            if (r.next()) {

                String data = r.getString("data");
                parserSnap = System.currentTimeMillis();
                Document doc = new Document(pageTitle, data);
                parserSnap = System.currentTimeMillis() - parserSnap;
                template.registerSymbol("__PARSER_SNAP__", "" + parserSnap);

                if (doc.isRedirect()) {
                    String redirect = doc.getRedirect();
                    response.sendRedirect(redirect);
                } else {

                    String dat = doc.toHTML();
                    template.registerSymbol("__CONTENT__", dat);
                    template.registerSymbol("__FLUSH_SNAP__", "0");

                    String buf = template.getBuffer();
                    buf = template.resolveSymbols(buf);
                    out.write(buf);
                    out.flush();
                }
            } else {

                redirectCreatePage(template, out, parserSnap);
            }

            template.clearSymtab();
            r.close();
            statement.close();
            statement = null;

        } catch (Exception ex) {
            System.out.println("doGet:" + ex);
        }
    }

    public void redirectCreatePage(Template template, BufferedWriter out, long parserSnap) {
        System.out.println("REDIRECT CREATE PAGE********");
        String dat = Globals.htmlRedirectPage;
        parserSnap = 0;

        template.registerSymbol("__CONTENT__", dat);
        template.registerSymbol("__FLUSH_SNAP__", "0");
        template.registerSymbol("__PARSER_SNAP__", "" + parserSnap);

        String buf = template.getBuffer();
        buf = template.resolveSymbols(buf);
        try {
            out.write(buf);
            out.flush();
        } catch (IOException ex) {
            //Logger.getLogger(Yawiki.class.getName()).log(Level.SEVERE, null, ex);
        }

    }

    public void doPost(HttpServletRequest request,
            HttpServletResponse response)
            throws IOException, ServletException {
        doGet(request, response);
    }
}
